home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / program / asm32.zip / SOLVE.DOC < prev    next >
Text File  |  1995-10-20  |  28KB  |  938 lines

  1.  
  2. *********************** MATHEMATICAL SOLUTIONS *****************************
  3.  
  4. ASM32's SOLVE subroutines are handy for many number crunching problems.
  5. Most SOLVE subroutines require a math coprocessor.  In subroutines
  6. requiring a math coprocessor, the coprocessor must have been initialized
  7. with FINIT or FNINIT before calling the subroutine.  See MathChip in
  8. SYSTEM.DOC.  Note that the 80x87 math coprocessors do not understand
  9. unsigned integers.
  10.  
  11.  
  12. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  13.  
  14. C2F:        convert degrees Celcius to degrees Fahrenheit
  15. Source:     f2c.asm
  16.  
  17. 80x87 required
  18.  
  19. Call with:  ST(0) = degrees Celcius
  20. Returns:    ST(0) = degrees Fahrenheit
  21. Uses:       ST(0), 80x87 flags
  22. Example:
  23.  
  24. include model.inc
  25.  
  26. extrn   c2f:near
  27.  
  28. include dataseg.inc
  29.  
  30. c0      dw 100           ; 100 degrees Celcius
  31. f0      dw ?             ; going to store degrees Fahrenheit here
  32.  
  33. @curseg ends
  34.  
  35. include codeseg.inc
  36.         .
  37.         .
  38.         .
  39.         fild   c0        ; load degrees Celcius into ST(0)
  40.         call   c2f       ; returns degrees Fahrenheit in ST(0)
  41.         fistp  f0        ; save degrees Fahrenheit and pop the 8087's stack
  42.  
  43.  
  44.  
  45. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  46.  
  47. CUBEFITF4:  fit a cubic equation to a set of float4 data
  48. CUBEFITF8:  fit a cubic equation to a set of float8 data
  49. CUBEFITI2:  fit a cubic equation to a set of integer2 data
  50. CUBEFITI4:  fit a cubic equation to a set of integer4 data
  51. Source:     cubefit.asm
  52.  
  53. 80x87 required
  54.  
  55.             CubeFit subroutines use the Least Squares method to calculate
  56.             the a, b, c and d coefficients of the equation
  57.  
  58.             y = a + bx + c(x^2) + d(x^3)
  59.  
  60.             which best fits the given data points.  See also QuadFit and
  61.             LineFit.
  62.             The data series at DS:[EBX] consists of n sets of x and y
  63.             coordinates.
  64.  
  65. Call with:  EBX pointing to data series
  66.             ECX = number of (x,y) points
  67. Returns:    ST(0) = a
  68.             ST(1) = b
  69.             ST(2) = c
  70.             ST(3) = d
  71. Uses:       entire 80x87 stack
  72. Example:
  73.  
  74. extrn   cubefiti2:near
  75.  
  76. include dataseg.inc
  77. points  dw 1,6           ; first (x,y) coordinate pair: x0 = 1, y0 = 6
  78.         dw 2,17          ; x1 = 2, y1 = 17
  79.         dw 5,86          ; x2 = 5, y2 = 86
  80.         dw 4,57          ; x3 = 4, y3 = 57
  81.         dw 3,34          ; x4 = 3, y4 = 34
  82. n equ ($-points) shr 2   ; number of coordinate pairs (5 in this case)
  83. @curseg ends
  84.  
  85. include codeseg.inc
  86.         .
  87.         .
  88.         .
  89.         lea   ebx,points  ; point to data series
  90.         mov   ecx,n       ; 5 data points
  91.         call  cubefiti2   ; returns ST(0) = a
  92.                           ;         ST(1) = b
  93.                           ;         ST(2) = c
  94.                           ;         ST(3) = d
  95.  
  96.  
  97. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  98.  
  99. DEG2RAD:    convert degrees of arc to radians
  100. Source:     deg2rad.asm
  101.  
  102. 80x87 required
  103.  
  104. Call with:  ST(0) = degrees of arc
  105. Returns:    ST(0) = radians
  106. Uses:       80x87 stack - ST(6) and ST(7) are lost
  107. Example:
  108.  
  109. extrn   deg2rad:near
  110.  
  111. include dataseg.inc
  112. deg     dw 180             ; dumb example - everyone knows this is pi radians
  113. @curseg ends
  114.  
  115. include codeseg .inc
  116.         .
  117.         .
  118.         .
  119.         fild   deg         ; load degrees into ST(0)
  120.         call   deg2rad     ; it comes back with ST(0) = radians
  121.  
  122.  
  123.  
  124. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  125.  
  126. F2C:        convert degrees Fahrenheit to degrees Celcius
  127. Source:     f2c.asm
  128.  
  129. 80x87 required
  130.  
  131. Call with:  ST(0) = degrees Fahrenheit
  132. Returns:    ST(0) = degrees Celcius
  133. Uses:       ST(0), 80x87 flags
  134. Example:
  135.  
  136. extrn   f2c:near
  137.  
  138. include dataseg.inc
  139. f0      dw 212           ; 212 degrees Farenheit
  140. c0      dw ?             ; going to store degrees Celcius here
  141. @curseg ends
  142.  
  143. include codeseg.inc
  144.         .
  145.         .
  146.         .
  147.         fild   f0        ; load degrees Fahrenheit into ST(0)
  148.         call   f2c       ; returns degrees Celcius in ST(0)
  149.         fistp  c0        ; save degrees Celcius and pop the 8087's stack
  150.  
  151.  
  152.  
  153. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  154.  
  155. FACTORIAL:  calculates the factorial of an integer
  156. Source:     factori.asm
  157.  
  158. 80x87 required
  159.  
  160. Call with:  EAX = signed integer value
  161. Returns:    ST(0) = factorial of the integer value
  162.             Note: factorials get very large with relatively small integers
  163. Uses:       ST(0); coprocessor stack is pushed, ST(7) is lost
  164. Example:
  165.  
  166.  
  167. extrn   factorial:near
  168.  
  169. include codeseg.inc
  170.         .
  171.         .
  172.         .
  173.         mov   eax,6          ; gonna calculate the factorial of 6
  174.         call  factorial
  175.  
  176.  
  177.  
  178. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  179.  
  180. FPRIMEI2:   calculate the derivative of a polynomial function
  181. Source:     fprimei2.asm
  182.  
  183. 80x87 NOT required
  184.  
  185. Call with:  ESI pointing to equation coefficients; all coefficients
  186.                must be 2-byte signed integers
  187.             ECX = order of polynomial (i. e., a quadratic function
  188.                is a second-order polynomial, so ECX = 2)
  189.                ECX limited to 0 < ECX < 32768
  190. Returns:    nothing
  191. Uses:       nothing
  192. Example:
  193.  
  194. extrn   fprimei2:near
  195.  
  196. include dataseg.inc
  197. fx      dw 2,0,3,2,0,5      ; the function y = 2+3*(x^2)+2*(x^3)+5*(x^5)
  198. @curseg ends
  199.  
  200. include codeseg.inc
  201.         .
  202.         .
  203.         .
  204.         mov     ecx,5        ; fifth order polynomial
  205.         lea     esi,fx       ; point to f(x) coefficients (2-byte integers)
  206.         call    fprimei2     ; calculate derivative of the function
  207.                              ; results:
  208.                              ; fx=0, fx+2=6, fx+4=6, fx+6=0, fx+8=25, fx+10=0
  209.  
  210.  
  211. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  212.  
  213. FPRIMEI4:   calculate the derivative of a polynomial function
  214. Source:     fprimei4.asm
  215.  
  216. 80x87 NOT required
  217.  
  218. Call with:  ESI pointing to equation coefficients; all coefficients
  219.                must be 4-byte signed integers
  220.             ECX = order of polynomial (i. e., a quadratic function
  221.                is a second-order polynomial, so ECX = 2)
  222.                ECX limited to 0 < ECX < 32768
  223. Returns:    nothing
  224. Uses:       nothing
  225. Example:
  226.  
  227. extrn   fprimei4:near
  228.  
  229. include dataseg.inc
  230.  
  231. fx      dd 2,0,3,2,0,5      ; the function y = 2+3*(x^2)+2*(x^3)+5*(x^5)
  232. @curseg ends
  233.  
  234. include codeseg.inc
  235.         .
  236.         .
  237.         .
  238.         mov     ecx,5        ; fifth order polynomial
  239.         lea     esi,fx       ; point to f(x) coefficients (2-byte integers)
  240.         call    fprimei4     ; calculate derivative of the function
  241.                              ; results:
  242.                              ; fx=0, fx+2=6, fx+4=6, fx+6=0, fx+8=25, fx+10=0
  243.  
  244.  
  245. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  246.  
  247. FPRIMEF4:   calculate the derivative of a polynomial function
  248. Source:     fprimef4.asm
  249.  
  250. 80x87 required
  251.  
  252. Call with:  ESI pointing to equation coefficients; all coefficients
  253.                must be float4 values
  254.             ECX = order of polynomial (i. e., a quadratic function
  255.                is a second-order polynomial, so ECX = 2)
  256.                0 < ECX < 32768
  257.  
  258. Returns:    nothing
  259. Uses:       nothing
  260. Example:
  261.  
  262. extrn   fprimef4:near
  263.  
  264. include dataseg.inc
  265.  
  266. fx      dd 2.2,0.0,3.5,2.0,0.0,5.1
  267.                             ; the function y = 2.2+3.5*(x^2)+2*(x^3)+5.1*(x^5)
  268. @curseg ends
  269.  
  270. include codeseg.inc
  271.         .
  272.         .
  273.         .
  274.         mov     ecx,5        ; fifth order polynomial
  275.         lea     esi,fx       ; point to f(x) coefficients (float4 values)
  276.         call    fprimef4     ; calculate derivative of the function
  277.  
  278.  
  279. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  280.  
  281. FPRIMEF8:   calculate the derivative of a polynomial function
  282. Source:     fprimef8.asm
  283.  
  284. 80x87 required
  285.  
  286. Call with:  ESI pointing to equation coefficients; all coefficients
  287.                must be float8 values
  288.             ECX = order of polynomial (i. e., a quadratic function
  289.                is a second-order polynomial, so ECX = 2)
  290.                0 < ECX < 32768
  291.  
  292. Returns:    nothing
  293. Uses:       nothing
  294. Example:
  295.  
  296. extrn   fprimef8:near
  297.  
  298. include dataseg.inc
  299.  
  300. fx      dq 2.2,0.0,3.5,2.0,0.0,5.1
  301.                             ; the function y = 2.2+3.5*(x^2)+2*(x^3)+5.1*(x^5)
  302. @curseg ends
  303.  
  304. include codeseg.inc
  305.         .
  306.         .
  307.         .
  308.         mov     ecx,5        ; fifth order polynomial
  309.         lea     esi,fx       ; point to f(x) coefficients (float4 values)
  310.         call    fprimef8     ; calculate derivative of the function
  311.  
  312.  
  313. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  314.  
  315. FVALUE:     calculate the future value of a given present value and
  316.             equal periodic payments
  317. Source:     fvalue.asm (xtothey.asm)
  318.  
  319. 80x87 required
  320.  
  321. Call with:  DS:[ESI] pointing to an ASM32 Financial data structure
  322.             (see FINDATA.INC).  The pv, n, i, and pmt data must be
  323.             current before calling fvalue.
  324. Returns:    updates fv in FINDATA data structure; future value also
  325.             returned in ST(0)
  326. Uses:       80x87 stack
  327. Evample:
  328.  
  329. include model.inc
  330. include findata.inc
  331.  
  332. extrn   fvalue:near
  333.  
  334. include dataseg.inc
  335.  
  336. case1   findata <12,.0525,100.0,10.0,> ; n = 12 periods
  337.                                        ; i = .0525 (5.25% interest rate per n)
  338.                                        ; present value = 100
  339.                                        ; 10 = payment per n period
  340. @curseg ends
  341.  
  342. include codeseg.inc
  343.          .
  344.          .
  345.          .
  346.          lea  esi,case1
  347.          call fvalue                    ; calculate future value; update
  348.                                         ; fv in case1
  349.  
  350. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  351.  
  352. ICOSINE:    return integer cosine*64k from integer angle
  353. ISINE:      return integer sine*64k from integer angle
  354. Source:     itrig.asm
  355.  
  356. Call with:  EAX = angle in degrees
  357. Returns:    (ICosine) EAX = cosine*64k of angle
  358.             (ISine)   EAX = sine*64k of angle
  359.  
  360.             Given an integer angle in degrees, these subroutines return a
  361.             biased sine or cosine.  The 64k bias results in sine or cosine
  362.             values returned in the range of 0 to 10000h.  After multiplying
  363.             these number by an integer, you should remove the bias by
  364.             shifting the result right 16 bits.  See example.
  365. Uses:       EAX, flags
  366. Example:
  367.  
  368. ; this code fragment is from ASM32's POLAR2RECT subroutine
  369.  
  370. extrn   isine, icosine
  371.  
  372. include codeseg.inc
  373.         .
  374.         .
  375.         .
  376.         movsx   eax,word ptr 6[ebx]     ; angle may be positive or negative
  377.         call    icosine                 ; get biased cosine
  378.         mov     edi,eax                 ; save cosine*64k
  379.  
  380.         movsx   eax,word ptr 4[ebx]     ; magnitude
  381.         imul    edi                     ; EAX = x-pixels*64k
  382.         movsx   edx,word ptr [ebx]      ; x-origin
  383.         sar     eax,16                  ; divide by 64k
  384.         mov     x0,dx
  385.         add     eax,edx                 ; plus origin
  386.         mov     x1,ax
  387.  
  388.  
  389. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  390.  
  391. LINEFITF4:  fit a line equation to a series of float4 data points
  392. LINEFITF8:  fit a line equation to a series of float8 data points
  393. LINEFITI2:  fit a line equation to a series of i2 data points
  394. LINEFITI4:  fit a line equation to a series of i4 data points
  395. Source:     linefit.asm
  396.  
  397. 80x87 required
  398.  
  399.             LineFit subroutines use the Least Squares method to calculate
  400.             the a and b coefficients of the equation
  401.  
  402.             y = a + bx
  403.  
  404.             which best fits the given data points.  See also CubeFit
  405.             and QuadFit.
  406.             The data series at DS:[EBX] consists of n sets of x and y
  407.             coordinates.
  408.  
  409. Call with:  EBX pointing to data series
  410.             ECX = number of (x,y) points
  411. Returns:    ST(0) = a
  412.             ST(1) = b
  413.             ST(2) = Σx
  414.             ST(3) = Σxx
  415.             ST(4) = Σy
  416.             ST(5) = Σxy
  417. Uses:       entire 80x87 stack
  418. Example:
  419.  
  420. extrn   linefiti2:near
  421.  
  422. include dataseg.inc
  423. points  dw 1,5           ; first (x,y) coordinate pair
  424.         dw 3,12          ; x1 = 3, y1 = 12
  425.         dw 7,24          ; x2 = 7, y2 = 24
  426.         dw 5,17          ; x3 = 5, y3 = 17
  427.         dw 10,33         ; x4 = 10, y4 = 33
  428. n equ ($-points) shr 2   ; number of coordinate pairs (5 in this case)
  429. @curseg ends
  430.  
  431. include codeseg.inc
  432.         .
  433.         .
  434.         .
  435.         lea   ebx,points  ; point to data series
  436.         mov   ecx,n       ; 5 data points
  437.         call  linefiti2   ; returns a in ST(0) and b in ST(1)
  438.  
  439.  
  440.  
  441. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  442.  
  443. NORMF4, NORMF4b:   normalize a float4 array
  444. Source:            normf4.asm (maxf4.asm)
  445.  
  446. NORMF8, NORMF8b:   normalize a float8 array
  447. Source:            normf8.asm (maxf8.asm)
  448.  
  449. 80x87 required
  450.  
  451. Call with:  EDI pointing to the numeric array
  452.             ECX = number of values in the array
  453.             ST(0) = number to normalize the array to
  454.             normf?b: EBX = bytes between data points
  455.             normf4 assumes EBX = 4, norm f8 assumes EBX = 8
  456.  
  457.             NormF4 and NormF8 assume that the maximum value of the data
  458.             is greater than zero.  I have used these subroutines
  459.             to scale data upward or downward, for example, to convert
  460.             from raw data to percent-of-maximum data.
  461.  
  462. Returns:    ST(0) = scaling factor
  463. Uses:       ST(0); ST(7) and ST(6) are pushed off the coprocessor stack
  464. Example:
  465.  
  466. include model.inc
  467.  
  468. extrn   normf4:near
  469.  
  470. include dataseg.inc
  471.  
  472. hundred dw 100            ; convert all data to percent-of-peak
  473.  
  474. @curseg ends
  475.  
  476. include codeseg.inc
  477.         .
  478.         .
  479.         .
  480.         esi    edi,f4fdata   ; EDI points to the data
  481.         mov    ecx,1488      ; half-hourly data for a month
  482.         fild   hundred       ; make the maximum value 100
  483.         call   normf4        ; normalize the data
  484.  
  485.  
  486.  
  487. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  488.  
  489. NPVALUE:    calculate net present value of an uneven cash flow
  490. Source:     npvalue.asm (xtothey.asm)
  491.  
  492. 80x87 required
  493.  
  494. Call with:  ESI pointing to ASM32's FINDATA data structure
  495.             EBX pointing to float4 cash flow data
  496.             n, i, and fv in FINDATA must be current before calling NPValue,
  497.             and there must be at least n cash flows
  498. Returns:    updates pv in FINDATA
  499.             ST(0) = present value
  500. Uses:       80x87 stack
  501. Example:
  502.  
  503. include   model.inc
  504.  
  505. include   findata.inc
  506.  
  507. extrn     npvalue:near
  508.  
  509. include dataseg.inc
  510.  
  511. case1     findata <30,.105,,,0.0>     ; 30 payments, 10.5% interest, fv = 0.0
  512. payments  dd 10 dup (80.0)            ; need 30 payments for this example
  513.           dd 10 dup (95.0)
  514.           dd 10 dup (103.0)
  515. @curseg ends
  516.  
  517. include codeseg.inc
  518.           .
  519.           .
  520.           .
  521.         lea    ebx,payments
  522.         lea    esi,case1
  523.         call   npvalue
  524.  
  525.  
  526.  
  527. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  528.  
  529. PAYMENT:    calculates periodic payment
  530. Source:     payment.asm
  531.  
  532. 80x87 required
  533.  
  534. Call with:  ESI pointing to ASM32's FINDATA data structure
  535.             n, i, fv and pv in FINDATA must be current before calling
  536.             Payment.  Payment replaces pmt in the data structure.
  537. Returns:    replaces pmt in data structure
  538. Uses:       80x87 stack; 80x86 registers and flags are unchanged
  539. Example:
  540.  
  541. include model.inc
  542. include findata.inc
  543.  
  544. extrn   payment:near
  545.  
  546. include dataseg.inc
  547.  
  548. ; 30 payments, 10.5% interest, pv = 10,000, fv = 0.0
  549.  
  550. case1   findata <30,.105,10000.0,,0.0>
  551.  
  552. @curseg ends
  553.  
  554. include codeseg.inc
  555.           .
  556.           .
  557.           .
  558.         lea    esi,case1
  559.         call   payment
  560.  
  561.  
  562.  
  563. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  564.  
  565. POLAR2RECT:  convert polar coordiantes to rectangular
  566. Source:      pol2rect.asm (itrig.asm)
  567.  
  568. Call with:   EBX pointing to polar vector data (see Example)
  569. Returns:     EBX pointing to rectangular coordinates in Polar2Rect's
  570.              data area.  Vector data is not disturbed.  Each call to
  571.              Polar2Rect will overwrite the results of the previous call.
  572.  
  573.              Note that if you want to use this subroutine to draw a
  574.              vector on a graphics screen, the vector's direction and
  575.              magnitude may not appear correct unless the graphics mode
  576.              has an x/y pixel ratio of 1:1.  Graphics screen dimensions
  577.              resulting in this pixel ratio are:
  578.  
  579.              320x240             VGA13x(1)
  580.              640x480             VGA 11h, 12h, SVGA256(1), SVGA32k(1)
  581.              800x600             VESA 6Ah, SVGA16(0), SVGA256(2), SVGA32k(2)
  582.              1024x768            SVGA16(1), SVGA256(3), SVGA32k(3)
  583.  
  584.              Also, because the screen's coordinate origin is at the top of
  585.              the screen, the y1 coordinate must be adjusted in order to
  586.              display the vector in a standard orientation.  See Example 1.
  587.  
  588.              Another way to display a vector in the proper orientation is
  589.              to set up a user-defined coordinate system with ASM32's UCINIT
  590.              and to convert the vector's rectangular coordinates to system
  591.              coordinates with UC2SYS.  See GRAPHICS.DOC and Example 2.
  592.  
  593. Uses:        EBX, flags
  594.  
  595. Examples on next page
  596.  
  597. (Polar2Rect, continued)
  598.  
  599. Example 1:
  600.  
  601. extrn   polar2rect:near, drawline:near
  602.  
  603. include dataseg.inc
  604. polar   dw 50,50                    ; (x,y) origin  -32768 to +32767
  605.         dw 300                      ; magnitude     -32768 to +32767
  606.         dw 207                      ; direction     -+degrees
  607. @curseg ends
  608.  
  609. include codeseg.inc
  610. ; code fragment assumes 1:1 pixel ratio
  611.         .
  612.         .
  613.         .
  614.         lea     ebx,polar
  615.         call    polar2rect          ; returns EBX -> rectangular data
  616.         movsx   eax,word ptr 6[ebx] ; y1
  617.         movsx   edx,word ptr 2[ebx] ; y0
  618.         sub     eax,edx             ; delta y
  619.         add     eax,eax             ; double it
  620.     sub    6[ebx],ax           ; adjust y1
  621.         call    drawline            ; on screen
  622.  
  623.  
  624.  
  625. Example 2:
  626.  
  627. extrn   polar2rect:near, drawline:near
  628. extrn   ucinit:near, uc2sys:near
  629.  
  630. include dataseg.inc
  631. ; user coordinates with 1:1 pixel ratio
  632. user    dw 0,0
  633.         dw 800,600
  634.  
  635. polar   dw 50,50                    ; (x,y) origin
  636.         dw 300                      ; magnitude
  637.         dw 207                      ; direction
  638. @curseg ends
  639.  
  640. include codeseg.inc
  641. ; set up user coordinates with 1:1 pixel ratio
  642.         lea     ebx,user            ; point to user coordinates
  643.         call    uc2sys
  644.         .
  645.         .
  646.         .
  647.         lea     ebx,polar
  648.         call    polar2rect          ; returns EBX -> rectangular data
  649.         call    uc2sys              ; convert to screen coordinates
  650.         call    drawline            ; on screen
  651.  
  652. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  653.  
  654. PSOLVEF4:   solve a polynomial equation for y, given x; float4 equation
  655.             coefficients
  656. Source:     psolvef4.asm
  657.  
  658. PSOLVEF8:   solve a polynomial equation for y, given x; float8 equation
  659.             coefficients
  660. Source:     psolvef8.asm
  661.  
  662. PSOLVEI2:   solve a polynomial equation for y, given x; 2-byte integer
  663.             equation coefficients
  664. Source:     psolvei2.asm
  665.  
  666. PSOLVEI4:   solve a polynomial equation for y, given x; 4-byte integer
  667.             equation coefficients
  668. Source:     psolvei4.asm
  669.  
  670. 80x87 required for all psolve subroutines
  671.  
  672. Call with:  ESI pointing to equation coefficients
  673.             ECX = n (order of the equation, i. e., a quadratic equation
  674.                is a second-order polynomial, so ECX = 2)
  675.             ST(0) = x value
  676. Returns:    ST(0) = y value
  677. Uses:       most coprocessor registers
  678. Example:
  679.  
  680. include model.inc
  681.  
  682. ; I want to calculate y for the equation
  683. ; y = 12 + 2x + 17(x**2) + 4(x**3)
  684.  
  685. extrn   psolvei2:near
  686.  
  687. include dataseg.inc
  688.  
  689. fx      dw 12,2,17,4
  690. n       equ 3              ; third-order equation
  691. x       dd 0.85
  692.  
  693. @curseg ends
  694.  
  695. include codeseg.inc
  696.         .
  697.         .
  698.         .
  699.         lea     esi,fx      ; DS:[ESI] points to equation coefficients
  700.         mov     ecx,n       ; a third-order polynomial
  701.         fld     x           ; find y given x
  702.         call    psolvei2    ; returns y in register ST(0)
  703.  
  704.  
  705.  
  706. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  707.  
  708. PVALUE:     calculate the present value of an even cash flow
  709. Source:     pvalue.asm (xtothey.asm)
  710.  
  711. 80x87 required
  712.  
  713. Call with:  [ESI] pointing to FINDATA data structure
  714.             n, i, pmt and fv must be updated before calling
  715.             pvalue.
  716. Returns:    updates pv in FINDATA data structure
  717.             ST(0) = present value
  718. Uses:       80x87 stack
  719. Example:
  720.  
  721. include  model.inc
  722.  
  723. include  findata.inc
  724.  
  725. extrn    pvalue:near
  726.  
  727. include  dataseg.inc
  728.  
  729. case1    findata <12,.0525,,10.0,0.0>   ; n = 12 periods
  730.                                         ; i = .0525 (5.25% interest rate per n)
  731.                                         ; present value unknown
  732.                                         ; payment per n period = 10
  733.                                         ; future value = 0
  734. @curseg ends
  735.  
  736. include  codeseg.inc
  737.          .
  738.          .
  739.          .
  740.          lea  esi,case1
  741.          call pvalue                    ; calculate present value; update
  742.                                         ; pv in case1
  743.  
  744.  
  745. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  746.  
  747. QUADFITF4:  fit a quadratic equation to a series of float4 data points
  748. QUADFITF8:  fit a quadratic equation to a series of float8 data points
  749. QUADFITI2:  fit a quadratic equation to a series of i2 data points
  750. QUADFITI4:  fit a quadratic equation to a series of i4 data points
  751. Source:     quadfit.asm
  752.  
  753. 80x87 required
  754.  
  755.             QuadFit subroutines use the Least Squares method to calculate
  756.             the a, b and c coefficients of the equation
  757.  
  758.             y = a + bx + c(x^2)
  759.  
  760.             which best fits the given data points.  See also CubeFit and
  761.             LineFit.
  762.             The data series at DS:[EBX] consists of n sets of x and y
  763.             coordinates.
  764.  
  765. Call with:  EBX pointing to data series
  766.             ECX = number of (x,y) points
  767. Returns:    ST(0) = a
  768.             ST(1) = b
  769.             ST(2) = c
  770. Uses:       entire 80x87 stack
  771. Example:
  772.  
  773. include model.inc
  774.  
  775. extrn   quadfiti2:near
  776.  
  777. include dataseg.inc
  778.  
  779. points  dw 1,6           ; first (x,y) coordinate pair: x0 = 1, y0 = 6
  780.         dw 2,17          ; x1 = 2, y1 = 17
  781.         dw 5,86          ; x2 = 5, y2 = 86
  782.         dw 4,57          ; x3 = 4, y3 = 57
  783.         dw 3,34          ; x4 = 3, y4 = 34
  784. n equ ($-points) shr 2   ; number of coordinate pairs (5 in this case)
  785.  
  786. @curseg ends
  787.  
  788. include codeseg.inc
  789.         .
  790.         .
  791.         .
  792.         lea   ebx,points  ; point to data series
  793.         mov   ecx,n       ; 5 data points
  794.         call  quadfiti2   ; returns a in ST(0), b in ST(1) and c in ST(2)
  795.  
  796.  
  797. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  798.  
  799. RAD2DEG:    convert radians to degrees of arc
  800. Source:     rad2deg.asm
  801.  
  802. 80x87 required
  803.  
  804. Call with:  ST(0) = radians
  805. Returns:    ST(0) = degrees of arc
  806. Uses:       80x87 stack - ST(6) and ST(7) are lost
  807. Example:
  808.  
  809. include codeseg.inc
  810. extrn   rad2deg:near
  811.  
  812. include dataseg.inc
  813.  
  814. rad     dd 3.14159        ; dumb example - everyone knows this is 180 degrees
  815.  
  816. @curseg ends
  817.  
  818. include codeseg.inc
  819.         .
  820.         .
  821.         .
  822.         fld    rad         ; load radians into ST(0)
  823.         call   rad2deg     ; it comes back with ST(0) = degrees
  824.  
  825.  
  826.  
  827. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  828.  
  829. RECT2POLAR:  convert rectangualr coordinates to polar coordinates
  830. Source:      rect2pol.asm (itrig.asm)
  831.  
  832. 80x87 required
  833.  
  834. Call with:   EBX pointing to rectangular coordinate data (see Example)
  835. Returns:     EBX pointing to polar coordinates in Rect2Polar's data area.
  836.              Input coordinate data is not disturbed.  Each call to
  837.              Rect2Polar will overwrite the results of the previous call.
  838. Uses:        EBX
  839.  
  840. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  841.  
  842. SAMP2POP:   convert sample standard deviation to population standard
  843.             deviation; used with StdDev subroutines.
  844. Source:     samp2pop.asm
  845.  
  846. 80x87 required
  847.  
  848. Call with:  ST(0) = sample standard deviation
  849.             ECX = n (number of data points)
  850. Returns:    ST(0) = population standard deviation
  851. Uses:       ST(0); ST(7), ST(6) and ST(5) are lost
  852. Example:    see StdDev series subroutines
  853.  
  854.  
  855. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  856.  
  857. STDDEVF4:   calculate standard deviation of a float4 data series 
  858. Source:     stddevf4.asm ($stddev.asm)
  859.  
  860. STDDEVF8:   calculate standard deviation of a float8 data series 
  861. Source:     stddevf8.asm ($stddev.asm)
  862.  
  863. STDDEVI2:   calculate standard deviation of an i2 data series 
  864. Source:     stddevi2.asm ($stddev.asm)
  865.  
  866. STDDEVI4:   calculate standard deviation of an i4 data series 
  867. Source:     stddevi4.asm ($stddev.asm)
  868.  
  869. 80x87 required
  870.  
  871. Call with:  EDI pointing to data series
  872.             ECX = number of values
  873.             Note that integer values are signed integers
  874. Returns:    if CF = 1, was called with ECX = 0
  875.             if CF = 0, ST(0) = standard deviation
  876.             The value returned by StdDev subroutines is the sample standard
  877.             deviation S; population standard deviation SP is calculated from
  878.             sample standard deviation with this formula:
  879.  
  880.             SP = S * SQRT((n - 1) / n)
  881.  
  882. Uses:       CF, coprocessor registers
  883. Example:
  884.  
  885. include model.inc
  886.  
  887. extrn   stddevf4:near       ; my data series is in float4 format
  888. extrn   samp2pop:near       ; I want the result as a
  889.                             ; population standard deviation
  890. include codeseg.inc
  891.         .
  892.         .
  893.         .
  894. ; the program has established a series of float4 values, and I need the
  895. ; standard deviation of the series
  896.         lea     edi,series_of_numbers
  897.         push    ds
  898.         pop     es
  899.         mov     ecx,1600       ; a whole bunch of data
  900.         call    stddevf4       ; ST(0) = sample standard deviation
  901.  
  902. ; the standard deviation returned by StdDev subroutines is the sample
  903. ; standard deviation.  Use samp2pop to convert to population standard
  904. ; deviation
  905.         call    samp2pop       ; ST(0) = population standard deviation
  906.  
  907. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  908.  
  909. XTOTHEY:    calculates x to the y power (x^y)
  910. Source:     xtothey.asm
  911.  
  912. 80x87 required
  913.  
  914. Call with:  ST(0) = x, ST(1) = y
  915. Returns:    ST(0) = x^y, coprocessor stack popped
  916. Uses:       coprocessor stack
  917. Example:
  918.  
  919. include model.inc
  920.  
  921. extrn   xtothey:near
  922.  
  923. include dataseg.inc
  924.  
  925. x       dd 17.4
  926. y       dd .3
  927.  
  928. @curseg ends
  929.  
  930. include codeseg.inc
  931.         .
  932.         .
  933.         .
  934.         fld    y                ; ST(0) = exponent
  935.         fld    x                ; ST(0) = x, ST(1) = exponent
  936.         call   xtothey          ; calculate x**y
  937.  
  938.